﻿using UnityEngine;
/// <summary>
/// 对象获取动画名称
/// </summary>
[System.Serializable]
public abstract class AnimSet : MonoBehaviour
{
	public abstract string GetIdleAnim(E_WeaponType weapon, E_WeaponState weaponState);

    public abstract string GetIdleActionAnim(E_WeaponType weapon, E_WeaponState weaponState);

    public abstract string GetMoveAnim(E_MotionType motion, E_MoveType move, E_WeaponType weapon, E_WeaponState weaponState);

    /// <summary>
    /// 旋转
    /// </summary>
    /// <param name="motionType"></param>
    /// <param name="rotationType"></param>
    /// <returns></returns>
    public abstract string GetRotateAnim(E_MotionType motionType, E_RotationType rotationType);

    /// <summary>
    /// 卷
    /// </summary>
    /// <param name="weapon"></param>
    /// <param name="weaponState"></param>
    /// <returns></returns>
    public abstract string GetRollAnim(E_WeaponType weapon, E_WeaponState weaponState);

    /// <summary>
    /// 阻档
    /// </summary>
    /// <param name="block"></param>
    /// <param name="weapon"></param>
    /// <returns></returns>
    public abstract string GetBlockAnim(E_BlockState block, E_WeaponType weapon);

    /// <summary>
    /// 击倒
    /// </summary>
    /// <param name="block"></param>
    /// <param name="weapon"></param>
    /// <returns></returns>
    public abstract string GetKnockdowAnim(E_KnockdownState block, E_WeaponType weapon);

    public abstract string GetShowWeaponAnim(E_WeaponType weapon);

    /// <summary>
    /// 隐藏武器
    /// </summary>
    /// <param name="weapon"></param>
    /// <returns></returns>
    public abstract string GetHideWeaponAnim(E_WeaponType weapon);

    /// <summary>
    /// 使用动作
    /// </summary>
    /// <param name="objectType"></param>
    /// <param name="interaction"></param>
    /// <returns></returns>
    public abstract string GetUseAnim(E_InteractionObjects objectType, E_InteractionType interaction);

    public abstract AnimAttackData GetFirstAttackAnim(E_WeaponType weapon, E_AttackType attackType);

    /// <summary>
    /// 获取连击的攻击动画
    /// </summary>
    /// <param name="parent"></param>
    /// <param name="attackType"></param>
    /// <returns></returns>
    public abstract AnimAttackData GetChainedAttackAnim(AnimAttackData parent, E_AttackType attackType);

    public virtual AnimAttackData GetRollAttackAnim() {return null;}

    /// <summary>
    /// 得到旋风攻击动画
    /// </summary>
    /// <returns></returns>
    public virtual AnimAttackData GetWhirlAttackAnim() { return null; }

    /// <summary>
    /// 受击动作阶段
    /// </summary>
    /// <param name="phase"></param>
    /// <returns></returns>
    public virtual string GetInjuryPhaseAnim(int phase) { return null; }

    public abstract string GetInjuryAnim(E_WeaponType weapon, E_DamageType type);

    public abstract string GetDeathAnim(E_WeaponType weapon, E_DamageType type);
}

public class AnimAttackData : System.Object
{
    /// <summary>
    /// 动作名称
    /// </summary>
    public string AnimName;

    public AnimAttackData[] NextAttacks = new AnimAttackData[(int)E_AttackType.Max];


    public float MoveDistance;// best attack distance

    //timers
    public float AttackMoveStartTime;
    public float AttackMoveEndTime;
    public float AttackEndTime;
    public float ZanshinEndTime;

    // hit parameters
    public float HitTime;
    public float HitDamage;
    public float HitAngle;
    public float HitMomentum;

    /// <summary>
    /// 命中 横 竖
    /// </summary>
    public E_CriticalHitType HitCriticalType;

    /// <summary>
    /// 击倒的
    /// </summary>
    public bool HitAreaKnockdown;
    /// <summary>
    /// 猜测是破碎
    /// </summary>
    public bool BreakBlock;
    /// <summary>
    /// 聚气？
    /// </summary>
    public bool UseImpuls;

    /// <summary>
    /// 临界变质剂
    /// </summary>
    public float CriticalModificator = 1;
    /// <summary>
    /// 慢动作
    /// </summary>
    public bool SloMotion;

    // trail
    public GameObject Trail;
    public Transform Parent;
    /// <summary>
    /// 尘土
    /// </summary>
    public GameObject Dust;
    /// <summary>
    /// 动画尘埃
    /// </summary>
    public Animation AnimationDust;
    public Animation Animation;
    public Material Material;
    public Material MaterialDust;

    //meni se v realtime, pro playera
    public bool FirstAttackInCombo = true;
    public bool LastAttackInCombo = false;
    public int ComboIndex;
    public bool FullCombo;
    public int ComboStep;


    //effects
    

    public AnimAttackData(string animName, GameObject trail, float moveDistance, float hitTime, float attackEndTime, float hitDamage, float hitAngle, float hitMomentum,
                    E_CriticalHitType criticalType, bool areaKnockDown )
    {
        AnimName = animName;
        Trail = trail;

        if (Trail)
        {
            Parent = Trail.transform.parent;

            if(Trail.transform.FindChild("dust"))
            {
                Dust = Trail.transform.FindChild("dust").gameObject;
                AnimationDust = Dust.GetComponent<Animation>();
                MaterialDust = Dust.GetComponent<Renderer>().material;
            }

            Animation = Trail.transform.parent.GetComponent<Animation>();
            if (Trail.GetComponentInChildren(typeof(Renderer)))
                Material = (Trail.GetComponentInChildren(typeof(Renderer)) as Renderer).material;
            else if (Trail.GetComponentInChildren(typeof(SkinnedMeshRenderer)))
                Material = (Trail.GetComponentInChildren(typeof(SkinnedMeshRenderer)) as Renderer).material;
            else
                Material = null;

            if (Material == null)
                Debug.LogError("Trail - no Material");
        }
        else
        {
            Animation = null;
            Material = null;
        }
        
        MoveDistance = moveDistance;

        AttackEndTime = attackEndTime;
        AttackMoveStartTime = 0;
        AttackMoveEndTime = AttackEndTime * 0.7f;

        HitTime = hitTime;
        HitDamage = hitDamage;
        HitAngle = hitAngle;
        HitMomentum = hitMomentum;
        HitCriticalType = criticalType;
        HitAreaKnockdown = areaKnockDown;
        BreakBlock = false;
        UseImpuls = false;
        CriticalModificator = 1;

    }

    public AnimAttackData(string animName, GameObject trail, float moveDistance, float hitTime, float moveStartTime, float moveEndTime, float attackEndTime, float hitDamage, float hitAngle, float hitMomentum,
                    E_CriticalHitType criticalType, float criticalMod, bool areaKnockDown, bool breakBlock, bool useImpuls, bool sloMotion)
    {
        AnimName = animName;
        Trail = trail;

        if (Trail)
        {
            Parent = Trail.transform.parent;

            if (Trail.transform.FindChild("dust"))
            {
                Dust = Trail.transform.FindChild("dust").gameObject;
                AnimationDust = Dust.GetComponent<Animation>();
                MaterialDust = Dust.GetComponent<Renderer>().material;
            }

            Animation = Trail.transform.parent.GetComponent<Animation>();
            if (Trail.GetComponent(typeof(Renderer)))
                Material = (Trail.GetComponent(typeof(Renderer)) as Renderer).material;
            else if (Trail.GetComponentInChildren(typeof(Renderer)))
                Material = (Trail.GetComponentInChildren(typeof(Renderer)) as Renderer).material;
            else if (Trail.GetComponentInChildren(typeof(SkinnedMeshRenderer)))
                Material = (Trail.GetComponentInChildren(typeof(SkinnedMeshRenderer)) as Renderer).material;
            else
                Material = null;

            if (Material == null)
                Debug.LogError("Trail - no Material");
        }
        else
        {
            Animation = null;
            Material = null;
        }

        MoveDistance = moveDistance;

        AttackMoveStartTime = moveStartTime;
        AttackMoveEndTime = moveEndTime;
        AttackEndTime = attackEndTime;

        HitTime = hitTime;
        HitDamage = hitDamage;
        HitAngle = hitAngle;
        HitMomentum = hitMomentum;
        HitCriticalType = criticalType;
        HitAreaKnockdown = areaKnockDown;
        BreakBlock = breakBlock;
        UseImpuls = useImpuls;
        CriticalModificator = criticalMod;
        SloMotion = sloMotion;
    }


    override public string ToString() { return base.ToString() + ": " + AnimName; }
}
